package app.dev.ems.web.wicket.page.login;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.SimpleFormComponentLabel;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.protocol.https.RequireHttps;
import org.apache.wicket.util.value.ValueMap;

import app.dev.ems.web.element.DialogProperties;
import app.dev.ems.web.element.HTMLAttributes;
import app.dev.ems.web.element.PageTitles;
import app.dev.ems.web.element.TipTipProperties;
import app.dev.ems.web.element.Titles;
import app.dev.ems.web.element.label.LabelElement;
import app.dev.ems.web.element.page.LoginPageElement;
import app.dev.ems.web.wicket.page.user.home.HomePage;
import app.dev.ems.web.wicket.session.EMSSession;

import com.google.code.jqwicket.ui.dialog.DialogOptions;
import com.google.code.jqwicket.ui.dialog.DialogWebMarkupContainer;
import com.google.code.jqwicket.ui.tiptip.TipTipBehavior;
import com.google.code.jqwicket.ui.tiptip.TipTipOptions;

@RequireHttps
public class LoginPage extends WebPage {

	private static final long serialVersionUID = -298979616675428637L;

	public LoginPage() {
		super();
		add(new Label(LoginPageElement.PAGE_TITLE.getElement(), new Model<String>(PageTitles.LOGIN_PAGE.getTitle())));
		add(new LoginForm(LoginPageElement.LOGIN_FORM.getElement()));
		EMSSession session = (EMSSession) getSession();
		if (session.isSignedIn()) {
			setResponsePage(HomePage.class);
		}
	}

	private final class LoginForm extends Form<Void> {

		private static final long serialVersionUID = -4255947604480137057L;

		private transient final ValueMap properties = new ValueMap();

		public LoginForm(final String formId) {
			super(formId);

			Label loginTitleLabel = new Label(LoginPageElement.LOGIN_TITLE.getElement(), new Model<String>(LabelElement.LOGIN_TITLE.getElement()));
			loginTitleLabel.setOutputMarkupPlaceholderTag(true);
			add(loginTitleLabel);

			Label welcomeMessageLabel = new Label(LoginPageElement.WELCOME_MESSAGE_LABEL.getElement(), new Model<String>(LabelElement.LOGIN_WELCOME_MESSAGE_LABEL.getElement()));
			welcomeMessageLabel.setOutputMarkupPlaceholderTag(true);
			add(welcomeMessageLabel);

			TextField<String> username = new TextField<String>(LoginPageElement.USERNAME.getElement(), new PropertyModel<String>(getProperties(), LoginPageElement.USERNAME.getElement()));
			username.add(new AttributeAppender(HTMLAttributes.TITLE.getAttribute(), new Model<String>(Titles.USERNAME.getTitle()))).add(getToolTip());
			username.setOutputMarkupPlaceholderTag(true);
			username.setLabel(new Model<String>(LabelElement.USERNAME_LABEL.getElement()));
			add(username);
			add(new SimpleFormComponentLabel(LoginPageElement.USERNAME_LABEL.getElement(), username));

			PasswordTextField password = new PasswordTextField(LoginPageElement.PASSWORD.getElement(), new PropertyModel<String>(getProperties(), LoginPageElement.PASSWORD.getElement()));
			password.add(new AttributeAppender(HTMLAttributes.TITLE.getAttribute(), new Model<String>(Titles.PASSWORD.getTitle()))).add(getToolTip());
			password.setOutputMarkupPlaceholderTag(true);
			password.setLabel(new Model<String>(LabelElement.PASSWORD_LABEL.getElement()));
			add(password);
			add(new SimpleFormComponentLabel(LoginPageElement.PASSWORD_LABEL.getElement(), password));

			final DialogWebMarkupContainer dialog = new DialogWebMarkupContainer(LoginPageElement.ERROR_DIALOG.getElement(), new DialogOptions().modal(true).resizable(false).openEvent(DialogProperties.LOGIN_ERROR_DIALOG_OPEN_EVENT.getDialogEvent().getEvent()).hideEffect(DialogProperties.LOGIN_ERROR_DIALOG_SHOW_EFFECT.getDialogEffect().getEffect()).showEffect(DialogProperties.LOGIN_ERROR_DIALOG_HIDE_EFFECT.getDialogEffect().getEffect()));
			add(dialog);

			final Label errorMessageLabel = new Label(LoginPageElement.LOGIN_ERROR_MESSAGE_LABEL.getElement());
			errorMessageLabel.setOutputMarkupPlaceholderTag(true);
			dialog.add(errorMessageLabel);

			final AjaxSubmitLink submitLink = new AjaxSubmitLink(LoginPageElement.SUBMIT_LINK.getElement(), this) {

				private static final long serialVersionUID = -3012385540575896874L;

				protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
					EMSSession session = (EMSSession) getSession();
					if (session.signIn(getUsername(), getPassword())) {
						if (!continueToOriginalDestination()) {
							setResponsePage(getApplication().getHomePage());
						}
					} else {
						errorMessageLabel.setDefaultModel(new Model<String>(LabelElement.LOGIN_ERROR_MESSAGE.getElement()));
						target.add(errorMessageLabel);
						dialog.open(target);
					}
				}

				protected void onError(final AjaxRequestTarget target, final Form<?> form) {

				}
			};
			submitLink.add(getToolTip());
			submitLink.setOutputMarkupPlaceholderTag(true);
			add(submitLink);

			password.add(new AjaxEventBehavior("onKeyPress") {

				private static final long serialVersionUID = 5061353574972223692L;

				@Override
				protected void onComponentTag(ComponentTag tag) {
					Component component = getComponent();
					if (component.isEnabled() && component.isEnableAllowed()) {
						StringBuilder javascript = new StringBuilder();
						javascript.append("if (event.keyCode == 13) {").append("$('#").append(submitLink.getMarkupId()).append("').click();").append("}");
						tag.put("onkeypress", javascript.toString());
					}
				}

				@Override
				protected void onEvent(AjaxRequestTarget target) {

				}
			});
		}

		public ValueMap getProperties() {
			return properties;
		}

		private String getPassword() {
			return getProperties().getString(LoginPageElement.PASSWORD.getElement());
		}

		private String getUsername() {
			return getProperties().getString(LoginPageElement.USERNAME.getElement());
		}

		private TipTipBehavior getToolTip() {
			return new TipTipBehavior(new TipTipOptions().maxWidth(TipTipProperties.MAX_WIDTH_AUTO.getMaxWidth().getWidth()).defaultPosition(TipTipProperties.POSITION_RIGHT.getPosition().getPosition()));
		}
	}
}